{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "from sklearn.datasets import fetch_openml\n",
    "import numpy as np\n",
    "from sklearn.neighbors import KNeighborsClassifier\n",
    "# 读取数据集内容,   读取本地\n",
    "mnist=fetch_openml('mnist_784')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 标签和训练数据\n",
    "X, y = mnist['data'], mnist['target']"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "X=np.array(X,dtype='uint8') \n",
    "y=np.array(y,dtype='uint8') "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 建立测试集\n",
    "X_train,X_test,y_train,y_test=X[:60000,:],X[60000:,:],y[:60000],y[60000:]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "import sklearn\n",
    "import matplotlib.pyplot as plt\n",
    "import pandas as pd"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 训练集洗牌赋值\n",
    "shuffle_index=np.random.permutation(60000)\n",
    "X_train,y_train=X_train[shuffle_index],y[shuffle_index]\n",
    "# 测试集洗牌赋值\n",
    "shuffle_index=np.random.permutation(10000)\n",
    "X_test,y_test=X_test[shuffle_index],y_test[shuffle_index]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [],
   "source": [
    "some_digit=X_train[23456]\n",
    "some_digit_img=some_digit.reshape(28,28)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "import matplotlib\n",
    "%matplotlib inline\n",
    "plt.imshow(some_digit_img,cmap=matplotlib.cm.binary)\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [],
   "source": [
    "from sklearn.neighbors import KNeighborsClassifier\n",
    "# 多标签分类 拿出为6的标签\n",
    "y_train_6=(y_train==6)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "KNeighborsClassifier()"
      ]
     },
     "execution_count": 10,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 算出距离\n",
    "kn_clf = KNeighborsClassifier()\n",
    "kn_clf.fit(X_train,y_train_6)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [],
   "source": [
    "some_digit=X_train[23456]\n",
    "some_digit=[some_digit]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([ True])"
      ]
     },
     "execution_count": 12,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 测试指定数据\n",
    "kn_clf.predict(some_digit)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "collapsed": true
   },
   "source": [
    "## GridSearchCV，它存在的意义就是自动调参，只要把参数输进去，就能给出最优化的结果和参数。但是这个方法适合于小数据集，一旦数据的量级上去了，很难得出结果。这个时候就是需要动脑筋了。数据量比较大的时候可以使用一个快速调优的方法——坐标下降。它其实是一种贪心算法：拿当前对模型影响最大的参数调优，直到最优化；再拿下一个影响最大的参数调优，如此下去，直到所有的参数调整完毕。这个方法的缺点就是可能会调到局部最优而不是全局最优，但是省时间省力，巨大的优势面前，还是试一试吧，后续可以再拿bagging再优化。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 2.参数说明\n",
    "# class sklearn.model_selection.GridSearchCV(estimator, param_grid, scoring=None, fit_params=None, n_jobs=1, iid=True, refit=True, cv=None, verbose=0, pre_dispatch=‘2*n_jobs’, error_score=’raise’, return_train_score=’warn’)\n",
    "\n",
    "# （1）       estimator\n",
    "\n",
    "# 选择使用的分类器，并且传入除需要确定最佳的参数之外的其他参数。每一个分类器都需要一个scoring参数，或者score方法：estimator=RandomForestClassifier(min_samples_split=100,min_samples_leaf=20,max_depth=8,max_features='sqrt',random_state=10),\n",
    "\n",
    "# （2）       param_grid\n",
    "\n",
    "# 需要最优化的参数的取值，值为字典或者列表，例如：param_grid =param_test1，param_test1 = {'n_estimators':range(10,71,10)}。\n",
    "\n",
    "# （3）       scoring=None\n",
    "\n",
    "# 模型评价标准，默认None,这时需要使用score函数；或者如scoring='roc_auc'，根据所选模型不同，评价准则不同。字符串（函数名），或是可调用对象，需要其函数签名形如：scorer(estimator, X, y)；如果是None，则使用estimator的误差估计函数。具体值的选取看本篇第三节内容。\n",
    "\n",
    "# （4）       fit_params=None\n",
    "\n",
    "# （5）       n_jobs=1\n",
    "\n",
    "# n_jobs: 并行数，int：个数,-1：跟CPU核数一致, 1:默认值\n",
    "\n",
    "# （6）       iid=True\n",
    "\n",
    "# iid:默认True,为True时，默认为各个样本fold概率分布一致，误差估计为所有样本之和，而非各个fold的平均。\n",
    "\n",
    "# （7）       refit=True\n",
    "\n",
    "# 默认为True,程序将会以交叉验证训练集得到的最佳参数，重新对所有可用的训练集与开发集进行，作为最终用于性能评估的最佳模型参数。即在搜索参数结束后，用最佳参数结果再次fit一遍全部数据集。\n",
    "\n",
    "# （8）        cv=None\n",
    "\n",
    "# 交叉验证参数，默认None，使用三折交叉验证。指定fold数量，默认为3，也可以是yield训练/测试数据的生成器。\n",
    "\n",
    "# （9）       verbose=0, scoring=None\n",
    "\n",
    "# verbose：日志冗长度，int：冗长度，0：不输出训练过程，1：偶尔输出，>1：对每个子模型都输出。\n",
    "\n",
    "# （10）   pre_dispatch=‘2*n_jobs’\n",
    "\n",
    "# 指定总共分发的并行任务数。当n_jobs大于1时，数据将在每个运行点进行复制，这可能导致OOM，而设置pre_dispatch参数，则可以预先划分总共的job数量，使数据最多被复制pre_dispatch次\n",
    "\n",
    "# （11）   error_score=’raise’\n",
    "\n",
    "# （12）   return_train_score=’warn’\n",
    "\n",
    "# 如果“False”，cv_results_属性将不包括训练分数\n",
    "\n",
    "# 回到sklearn里面的GridSearchCV，GridSearchCV用于系统地遍历多种参数组合，通过交叉验证确定最佳效果参数。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Fitting 5 folds for each of 6 candidates, totalling 30 fits\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "[Parallel(n_jobs=8)]: Using backend LokyBackend with 8 concurrent workers.\n"
     ]
    }
   ],
   "source": [
    "from sklearn.model_selection import GridSearchCV\n",
    "\n",
    "param_grid = [{'weights': [\"uniform\", \"distance\"], 'n_neighbors': [3, 4, 5]}]  #需要最优化的参数的取值\n",
    "\n",
    "knn_clf = KNeighborsClassifier()\n",
    "grid_search = GridSearchCV(knn_clf, param_grid, cv=5, verbose=3, n_jobs=8)\n",
    "grid_search.fit(X_train, y_train)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "grid_search.best_params_\n",
    "grid_search.best_score_"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from sklearn.metrics import accuracy_score\n",
    "\n",
    "y_pred = grid_search.predict(X_test)\n",
    "accuracy_score(y_test, y_pred)"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
